package goods_serv

import (
	"strconv"
	"strings"
	"ubt-aio-service/app/mod/goods_mod"
	"ubt-aio-service/app/pkg/db"
	"ubt-aio-service/app/utils"
)

type brand struct{}

var BrandServ = brand{}

// Add 新增
func (s *brand) Add(req *goods_mod.BrandSaveReq) *utils.ResJson {
	// 去掉主键，改为自动赋值模式
	sqlStr := "INSERT INTO goods_brand(brand_name, brand_code, fst_char, quanpin, jianpin, kind, sort, logo_id, logo_name, logo_url, remarks, states, add_time, upd_time) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, 1, EXTRACT(epoch FROM NOW()), EXTRACT(epoch FROM NOW()))"
	return db.CudData(sqlStr, req.BrandName, req.BrandCode, req.FstChar, req.Quanpin, req.Jianpin, req.Kind, req.Sort, req.LogoId, req.LogoName, req.LogoUrl, req.Remarks)
}

// Exists 判断是否重复
func (s *brand) Exists(req *goods_mod.BrandExtVo) bool {
	// 注意修改对应的变量值
	sqlStr := "SELECT brand_id FROM goods_brand WHERE states!=2 AND kind=$1 AND brand_code=$2"
	param := make([]any, 0)
	param = append(param, req.Kind)
	param = append(param, req.Code)
	if req.Id != "" {
		sqlStr += " AND brand_id!=$3"
		param = append(param, req.Id)
	}
	if res := db.GetOne(sqlStr, param...); res.Code == utils.Succeed.Code {
		return true
	}
	return false
}

// Update 修改
func (s *brand) Update(req *goods_mod.BrandSaveReq) *utils.ResJson {
	// 注意最后的索引值修改，以及去掉不需要修改的值
	sqlStr := "UPDATE goods_brand SET brand_name=$1, brand_code=$2, fst_char=$3, quanpin=$4, jianpin=$5, kind=$6, sort=$7, logo_id=$8, logo_name=$9, logo_url=$10, remarks=$11, upd_time=EXTRACT(epoch FROM NOW()) WHERE brand_id=$12"
	// 需要将第一个值放到最后
	return db.CudData(sqlStr, req.BrandName, req.BrandCode, req.FstChar, req.Quanpin, req.Jianpin, req.Kind, req.Sort, req.LogoId, req.LogoName, req.LogoUrl, req.Remarks, req.BrandId)
}

// Process 删除
func (s *brand) Process(req *goods_mod.BrandDelsReq) *utils.ResJson {
	var (
		param []any
		q     string
		n     = 1
	)
	param = append(param, req.States)
	idList := strings.Split(req.Ids, ",")
	for _, curId := range idList {
		n++
		q += "$" + strconv.Itoa(n) + ","
		param = append(param, curId)
	}
	q = q[:len(q)-1]
	sqlStr := "UPDATE goods_brand SET states=$1, upd_time=EXTRACT(epoch FROM NOW()) WHERE brand_id IN (" + q + ")"
	return db.CudData(sqlStr, param...)
}

// One 获取详情
func (s *brand) One(brandId string) *utils.ResJson {
	sqlStr := "SELECT a.brand_id, a.brand_name, a.brand_code, a.fst_char, a.quanpin, a.jianpin, a.kind, a.sort, a.logo_id, a.logo_name, a.logo_url, a.remarks, a.states, a.add_time, a.upd_time FROM goods_brand a WHERE a.brand_id=$1"
	return db.GetOne(sqlStr, brandId)
}

// Count 获取数量
func (s *brand) Count(req *goods_mod.BrandPageReq) *utils.ResJson {
	sqlStr := "SELECT COUNT(1) AS nums FROM goods_brand WHERE states!=2"
	param := make([]any, 0)
	var n = 0
	if req.Keywords != "" {
		sqlStr += " AND ("
		nameArr := strings.Split(req.Keywords, " ")
		for _, name := range nameArr {
			sqlStr += "brand_name LIKE '%'||$" + strconv.Itoa(n+1) + "||'%' OR " +
				"brand_code LIKE '%'||$" + strconv.Itoa(n+2) + "||'%' OR "
			param = append(param, name)
			param = append(param, name)
			n += 2
		}
		sqlStr = sqlStr[:len(sqlStr)-4]
		sqlStr += ")"
	}
	if req.Kind != 0 {
		sqlStr += " AND kind=$" + strconv.Itoa(n+1)
		param = append(param, req.Kind)
		n++
	}
	if res := db.GetOne(sqlStr, param...); res.Code == utils.Succeed.Code && res.Data.(map[string]any)["nums"].(int64) > 0 {
		return res
	}
	return utils.NoData
}

// Page 获取分页列表
func (s *brand) Page(req *goods_mod.BrandPageReq) *utils.ResJson {
	sqlStr := "SELECT a.brand_id, a.brand_name, a.brand_code, a.fst_char, a.kind, a.sort, a.logo_name, a.logo_url, a.states, a.add_time " +
		"FROM goods_brand a " +
		"WHERE a.states!=2"
	param := make([]any, 0)
	var n = 0
	if req.Keywords != "" {
		sqlStr += " AND ("
		nameArr := strings.Split(req.Keywords, " ")
		for _, name := range nameArr {
			sqlStr += "a.brand_name LIKE '%'||$" + strconv.Itoa(n+1) + "||'%' OR " +
				"a.brand_code LIKE '%'||$" + strconv.Itoa(n+2) + "||'%' OR " +
				"a.fst_char LIKE '%'||$" + strconv.Itoa(n+3) + "||'%' OR "
			param = append(param, name)
			param = append(param, name)
			n += 3
		}
		sqlStr = sqlStr[:len(sqlStr)-4]
		sqlStr += ")"
	}
	if req.Kind != 0 {
		sqlStr += " AND kind=$" + strconv.Itoa(n+1)
		param = append(param, req.Kind)
		n++
	}
	sqlStr += " ORDER BY a.sort LIMIT $" + strconv.Itoa(n+1) + " OFFSET $" + strconv.Itoa(n+2)
	param = append(param, req.Limit)
	param = append(param, req.Offset)
	return db.GetAll(sqlStr, param...)
}

// Sort 获取数量，用于排序
func (s *brand) Sort(kind uint8) *utils.ResJson {
	sqlStr := "SELECT COUNT(1)+1 AS nums FROM goods_brand WHERE states=1 AND kind=$1"
	res := db.GetOne(sqlStr, kind)
	return &utils.ResJson{Code: utils.Succeed.Code, Msg: utils.Succeed.Msg, Data: res.Data.(map[string]any)["nums"].(int64)}
}

// Select 获取选择列表
func (s *brand) Select(kind uint8, typeId string) *utils.ResJson {
	sqlStr := "SELECT a.brand_id AS sel_id, a.brand_name AS sel_name, a.brand_code AS sel_code " +
		"FROM goods_brand a WHERE a.states=1 AND kind=$1 "
	if typeId != "" {
		sqlStr += "AND (SELECT brand_ids FROM goods_type b WHERE b.type_id=$2) LIKE '%'||a.brand_id||'%'"
	}
	sqlStr += " ORDER BY a.sort"
	return db.GetAll(sqlStr, kind, typeId)
}

// List 获取列表
func (s *brand) List(kind uint8) *utils.ResJson {
	sqlStr := "SELECT a.brand_id, a.brand_name, a.logo_name, a.logo_url, false AS chked FROM goods_brand a WHERE a.states=1 AND kind=$1 ORDER BY a.sort"
	return db.GetAll(sqlStr, kind)
}
